using DocumentCreationSystem.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using System.Text.Json;
using System.Reflection;
using System.Collections.Concurrent;
using System.IO;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 插件生态系统服务 - 支持第三方功能扩展的可扩展插件架构
    /// </summary>
    public interface IPluginEcosystemService
    {
        Task<List<PluginInfo>> GetAvailablePluginsAsync();
        Task<List<PluginInfo>> GetInstalledPluginsAsync();
        Task<PluginInstallResult> InstallPluginAsync(string pluginId, string source);
        Task<bool> UninstallPluginAsync(string pluginId);
        Task<bool> EnablePluginAsync(string pluginId);
        Task<bool> DisablePluginAsync(string pluginId);
        Task<PluginExecutionResult> ExecutePluginAsync(string pluginId, string action, Dictionary<string, object> parameters);
        Task<List<PluginHook>> GetPluginHooksAsync(string hookPoint);
        Task RegisterPluginHookAsync(string pluginId, PluginHook hook);
        Task<PluginConfiguration> GetPluginConfigurationAsync(string pluginId);
        Task UpdatePluginConfigurationAsync(string pluginId, PluginConfiguration configuration);
        Task<List<PluginDependency>> CheckPluginDependenciesAsync(string pluginId);
        Task<PluginValidationResult> ValidatePluginAsync(string pluginPath);
    }

    public class PluginEcosystemService : IPluginEcosystemService
    {
        private readonly ILogger<PluginEcosystemService> _logger;
        private readonly IDataStorageService _dataStorage;
        private readonly string _pluginsPath;
        private readonly ConcurrentDictionary<string, IPlugin> _loadedPlugins = new();
        private readonly ConcurrentDictionary<string, PluginHook> _registeredHooks = new();

        public PluginEcosystemService(
            ILogger<PluginEcosystemService> logger,
            IDataStorageService dataStorage,
            IConfiguration configuration)
        {
            _logger = logger;
            _dataStorage = dataStorage;
            _pluginsPath = configuration["Plugins:Path"] ?? "plugins";
            
            // 确保插件目录存在
            Directory.CreateDirectory(_pluginsPath);
            
            // 初始化时加载已安装的插件
            _ = Task.Run(LoadInstalledPluginsAsync);
        }

        /// <summary>
        /// 获取可用插件列表
        /// </summary>
        public async Task<List<PluginInfo>> GetAvailablePluginsAsync()
        {
            try
            {
                var availablePlugins = new List<PluginInfo>();

                // 从本地插件目录扫描
                var localPlugins = await ScanLocalPluginsAsync();
                availablePlugins.AddRange(localPlugins);

                // 从插件仓库获取（如果配置了）
                var repositoryPlugins = await FetchRepositoryPluginsAsync();
                availablePlugins.AddRange(repositoryPlugins);

                // 去重并排序
                availablePlugins = availablePlugins
                    .GroupBy(p => p.Id)
                    .Select(g => g.OrderByDescending(p => p.Version).First())
                    .OrderBy(p => p.Name)
                    .ToList();

                _logger.LogInformation($"发现 {availablePlugins.Count} 个可用插件");
                return availablePlugins;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取可用插件列表失败");
                return new List<PluginInfo>();
            }
        }

        /// <summary>
        /// 获取已安装插件列表
        /// </summary>
        public async Task<List<PluginInfo>> GetInstalledPluginsAsync()
        {
            try
            {
                var installedPlugins = await _dataStorage.GetAsync<List<PluginInfo>>("installed_plugins") ?? new List<PluginInfo>();
                
                // 验证插件文件是否仍然存在
                var validPlugins = new List<PluginInfo>();
                foreach (var plugin in installedPlugins)
                {
                    var pluginPath = Path.Combine(_pluginsPath, plugin.Id);
                    if (Directory.Exists(pluginPath))
                    {
                        validPlugins.Add(plugin);
                    }
                }

                // 更新已安装插件列表
                if (validPlugins.Count != installedPlugins.Count)
                {
                    await _dataStorage.SaveAsync("installed_plugins", validPlugins);
                }

                return validPlugins;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取已安装插件列表失败");
                return new List<PluginInfo>();
            }
        }

        /// <summary>
        /// 安装插件
        /// </summary>
        public async Task<PluginInstallResult> InstallPluginAsync(string pluginId, string source)
        {
            try
            {
                _logger.LogInformation($"开始安装插件: {pluginId} from {source}");

                var result = new PluginInstallResult
                {
                    PluginId = pluginId,
                    Source = source,
                    StartTime = DateTime.Now
                };

                // 检查插件是否已安装
                var installedPlugins = await GetInstalledPluginsAsync();
                if (installedPlugins.Any(p => p.Id == pluginId))
                {
                    result.Success = false;
                    result.ErrorMessage = "插件已安装";
                    return result;
                }

                // 下载或复制插件文件
                var pluginPath = Path.Combine(_pluginsPath, pluginId);
                await DownloadPluginAsync(source, pluginPath);

                // 验证插件
                var validationResult = await ValidatePluginAsync(pluginPath);
                if (!validationResult.IsValid)
                {
                    result.Success = false;
                    result.ErrorMessage = $"插件验证失败: {string.Join(", ", validationResult.Errors)}";
                    
                    // 清理下载的文件
                    if (Directory.Exists(pluginPath))
                    {
                        Directory.Delete(pluginPath, true);
                    }
                    return result;
                }

                // 检查依赖
                var dependencies = await CheckPluginDependenciesAsync(pluginId);
                var missingDependencies = dependencies.Where(d => !d.IsSatisfied).ToList();
                if (missingDependencies.Any())
                {
                    result.Success = false;
                    result.ErrorMessage = $"缺少依赖: {string.Join(", ", missingDependencies.Select(d => d.Name))}";
                    return result;
                }

                // 加载插件
                var pluginInfo = await LoadPluginInfoAsync(pluginPath);
                var plugin = await LoadPluginAsync(pluginPath);

                if (plugin != null)
                {
                    _loadedPlugins[pluginId] = plugin;

                    // 初始化插件
                    await plugin.InitializeAsync();

                    // 更新已安装插件列表
                    installedPlugins.Add(pluginInfo);
                    await _dataStorage.SaveAsync("installed_plugins", installedPlugins);

                    result.Success = true;
                    result.InstalledPlugin = pluginInfo;
                    result.EndTime = DateTime.Now;

                    _logger.LogInformation($"插件安装成功: {pluginId}");
                }
                else
                {
                    result.Success = false;
                    result.ErrorMessage = "插件加载失败";
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"安装插件失败: {pluginId}");
                return new PluginInstallResult
                {
                    PluginId = pluginId,
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 卸载插件
        /// </summary>
        public async Task<bool> UninstallPluginAsync(string pluginId)
        {
            try
            {
                _logger.LogInformation($"开始卸载插件: {pluginId}");

                // 禁用插件
                await DisablePluginAsync(pluginId);

                // 从内存中移除
                if (_loadedPlugins.TryRemove(pluginId, out var plugin))
                {
                    await plugin.DisposeAsync();
                }

                // 删除插件文件
                var pluginPath = Path.Combine(_pluginsPath, pluginId);
                if (Directory.Exists(pluginPath))
                {
                    Directory.Delete(pluginPath, true);
                }

                // 更新已安装插件列表
                var installedPlugins = await GetInstalledPluginsAsync();
                installedPlugins.RemoveAll(p => p.Id == pluginId);
                await _dataStorage.SaveAsync("installed_plugins", installedPlugins);

                // 移除注册的钩子
                var hooksToRemove = _registeredHooks.Where(kvp => kvp.Value.PluginId == pluginId).ToList();
                foreach (var hook in hooksToRemove)
                {
                    _registeredHooks.TryRemove(hook.Key, out _);
                }

                _logger.LogInformation($"插件卸载成功: {pluginId}");
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"卸载插件失败: {pluginId}");
                return false;
            }
        }

        /// <summary>
        /// 启用插件
        /// </summary>
        public async Task<bool> EnablePluginAsync(string pluginId)
        {
            try
            {
                if (_loadedPlugins.TryGetValue(pluginId, out var plugin))
                {
                    await plugin.EnableAsync();
                    
                    // 更新插件状态
                    await UpdatePluginStatusAsync(pluginId, PluginStatus.Enabled);
                    
                    _logger.LogInformation($"插件已启用: {pluginId}");
                    return true;
                }

                _logger.LogWarning($"插件未找到: {pluginId}");
                return false;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"启用插件失败: {pluginId}");
                return false;
            }
        }

        /// <summary>
        /// 禁用插件
        /// </summary>
        public async Task<bool> DisablePluginAsync(string pluginId)
        {
            try
            {
                if (_loadedPlugins.TryGetValue(pluginId, out var plugin))
                {
                    await plugin.DisableAsync();
                    
                    // 更新插件状态
                    await UpdatePluginStatusAsync(pluginId, PluginStatus.Disabled);
                    
                    _logger.LogInformation($"插件已禁用: {pluginId}");
                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"禁用插件失败: {pluginId}");
                return false;
            }
        }

        /// <summary>
        /// 执行插件功能
        /// </summary>
        public async Task<PluginExecutionResult> ExecutePluginAsync(string pluginId, string action, Dictionary<string, object> parameters)
        {
            try
            {
                if (!_loadedPlugins.TryGetValue(pluginId, out var plugin))
                {
                    return new PluginExecutionResult
                    {
                        Success = false,
                        ErrorMessage = "插件未找到或未加载"
                    };
                }

                var result = await plugin.ExecuteAsync(action, parameters);
                
                _logger.LogDebug($"插件执行完成: {pluginId}.{action}");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"插件执行失败: {pluginId}.{action}");
                return new PluginExecutionResult
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 获取插件钩子
        /// </summary>
        public async Task<List<PluginHook>> GetPluginHooksAsync(string hookPoint)
        {
            try
            {
                var hooks = _registeredHooks.Values
                    .Where(h => h.HookPoint == hookPoint && h.IsEnabled)
                    .OrderBy(h => h.Priority)
                    .ToList();

                return hooks;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取插件钩子失败: {hookPoint}");
                return new List<PluginHook>();
            }
        }

        /// <summary>
        /// 注册插件钩子
        /// </summary>
        public async Task RegisterPluginHookAsync(string pluginId, PluginHook hook)
        {
            try
            {
                hook.PluginId = pluginId;
                var hookKey = $"{pluginId}_{hook.HookPoint}_{hook.Id}";
                _registeredHooks[hookKey] = hook;

                _logger.LogDebug($"插件钩子已注册: {hookKey}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"注册插件钩子失败: {pluginId}");
            }
        }

        /// <summary>
        /// 获取插件配置
        /// </summary>
        public async Task<PluginConfiguration> GetPluginConfigurationAsync(string pluginId)
        {
            try
            {
                var config = await _dataStorage.GetAsync<PluginConfiguration>($"plugin_config_{pluginId}");
                return config ?? new PluginConfiguration { PluginId = pluginId };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取插件配置失败: {pluginId}");
                return new PluginConfiguration { PluginId = pluginId };
            }
        }

        /// <summary>
        /// 更新插件配置
        /// </summary>
        public async Task UpdatePluginConfigurationAsync(string pluginId, PluginConfiguration configuration)
        {
            try
            {
                configuration.PluginId = pluginId;
                configuration.UpdatedAt = DateTime.Now;
                
                await _dataStorage.SaveAsync($"plugin_config_{pluginId}", configuration);

                // 通知插件配置已更新
                if (_loadedPlugins.TryGetValue(pluginId, out var plugin))
                {
                    await plugin.OnConfigurationUpdatedAsync(configuration);
                }

                _logger.LogInformation($"插件配置已更新: {pluginId}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新插件配置失败: {pluginId}");
            }
        }

        /// <summary>
        /// 检查插件依赖
        /// </summary>
        public async Task<List<PluginDependency>> CheckPluginDependenciesAsync(string pluginId)
        {
            try
            {
                var pluginPath = Path.Combine(_pluginsPath, pluginId);
                var manifestPath = Path.Combine(pluginPath, "plugin.json");

                if (!File.Exists(manifestPath))
                {
                    return new List<PluginDependency>();
                }

                var manifestJson = await File.ReadAllTextAsync(manifestPath);
                var manifest = JsonSerializer.Deserialize<PluginManifest>(manifestJson);

                var dependencies = new List<PluginDependency>();
                var installedPlugins = await GetInstalledPluginsAsync();

                foreach (var dep in manifest?.Dependencies ?? new List<PluginDependencyInfo>())
                {
                    var dependency = new PluginDependency
                    {
                        Name = dep.Name,
                        Version = dep.Version,
                        IsOptional = dep.IsOptional
                    };

                    // 检查是否已安装
                    var installedPlugin = installedPlugins.FirstOrDefault(p => p.Name == dep.Name);
                    if (installedPlugin != null)
                    {
                        dependency.IsSatisfied = IsVersionCompatible(installedPlugin.Version, dep.Version);
                        dependency.InstalledVersion = installedPlugin.Version;
                    }
                    else
                    {
                        dependency.IsSatisfied = dep.IsOptional;
                    }

                    dependencies.Add(dependency);
                }

                return dependencies;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"检查插件依赖失败: {pluginId}");
                return new List<PluginDependency>();
            }
        }

        /// <summary>
        /// 验证插件
        /// </summary>
        public async Task<PluginValidationResult> ValidatePluginAsync(string pluginPath)
        {
            try
            {
                var result = new PluginValidationResult();

                // 检查插件清单文件
                var manifestPath = Path.Combine(pluginPath, "plugin.json");
                if (!File.Exists(manifestPath))
                {
                    result.Errors.Add("缺少插件清单文件 plugin.json");
                    return result;
                }

                // 解析清单文件
                var manifestJson = await File.ReadAllTextAsync(manifestPath);
                PluginManifest? manifest;
                try
                {
                    manifest = JsonSerializer.Deserialize<PluginManifest>(manifestJson);
                }
                catch (JsonException ex)
                {
                    result.Errors.Add($"插件清单文件格式错误: {ex.Message}");
                    return result;
                }

                if (manifest == null)
                {
                    result.Errors.Add("插件清单文件为空");
                    return result;
                }

                // 验证必需字段
                if (string.IsNullOrEmpty(manifest.Id))
                    result.Errors.Add("插件ID不能为空");
                if (string.IsNullOrEmpty(manifest.Name))
                    result.Errors.Add("插件名称不能为空");
                if (string.IsNullOrEmpty(manifest.Version))
                    result.Errors.Add("插件版本不能为空");
                if (string.IsNullOrEmpty(manifest.EntryPoint))
                    result.Errors.Add("插件入口点不能为空");

                // 检查入口点文件
                var entryPointPath = Path.Combine(pluginPath, manifest.EntryPoint);
                if (!File.Exists(entryPointPath))
                {
                    result.Errors.Add($"入口点文件不存在: {manifest.EntryPoint}");
                }

                // 检查权限声明
                if (manifest.Permissions?.Any() == true)
                {
                    foreach (var permission in manifest.Permissions)
                    {
                        if (!IsValidPermission(permission))
                        {
                            result.Warnings.Add($"未知权限: {permission}");
                        }
                    }
                }

                result.IsValid = !result.Errors.Any();
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"验证插件失败: {pluginPath}");
                return new PluginValidationResult
                {
                    IsValid = false,
                    Errors = { ex.Message }
                };
            }
        }

        #region 私有辅助方法

        private async Task LoadInstalledPluginsAsync()
        {
            try
            {
                var installedPlugins = await GetInstalledPluginsAsync();
                foreach (var pluginInfo in installedPlugins)
                {
                    if (pluginInfo.Status == PluginStatus.Enabled)
                    {
                        var pluginPath = Path.Combine(_pluginsPath, pluginInfo.Id);
                        var plugin = await LoadPluginAsync(pluginPath);
                        if (plugin != null)
                        {
                            _loadedPlugins[pluginInfo.Id] = plugin;
                            await plugin.InitializeAsync();
                        }
                    }
                }

                _logger.LogInformation($"已加载 {_loadedPlugins.Count} 个插件");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "加载已安装插件失败");
            }
        }

        private async Task<List<PluginInfo>> ScanLocalPluginsAsync()
        {
            var plugins = new List<PluginInfo>();

            if (!Directory.Exists(_pluginsPath))
                return plugins;

            var pluginDirectories = Directory.GetDirectories(_pluginsPath);
            foreach (var pluginDir in pluginDirectories)
            {
                try
                {
                    var pluginInfo = await LoadPluginInfoAsync(pluginDir);
                    plugins.Add(pluginInfo);
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"加载插件信息失败: {pluginDir}");
                }
            }

            return plugins;
        }

        private async Task<List<PluginInfo>> FetchRepositoryPluginsAsync()
        {
            // 从插件仓库获取插件列表的实现
            // 这里可以集成插件商店或仓库API
            await Task.Delay(10);
            return new List<PluginInfo>();
        }

        private async Task<PluginInfo> LoadPluginInfoAsync(string pluginPath)
        {
            var manifestPath = Path.Combine(pluginPath, "plugin.json");
            var manifestJson = await File.ReadAllTextAsync(manifestPath);
            var manifest = JsonSerializer.Deserialize<PluginManifest>(manifestJson);

            return new PluginInfo
            {
                Id = manifest?.Id ?? Path.GetFileName(pluginPath),
                Name = manifest?.Name ?? "Unknown Plugin",
                Version = manifest?.Version ?? "1.0.0",
                Description = manifest?.Description ?? "",
                Author = manifest?.Author ?? "Unknown",
                Category = manifest?.Category ?? "General",
                Status = PluginStatus.Disabled,
                InstallPath = pluginPath,
                Manifest = manifest
            };
        }

        private async Task<IPlugin?> LoadPluginAsync(string pluginPath)
        {
            try
            {
                var manifestPath = Path.Combine(pluginPath, "plugin.json");
                var manifestJson = await File.ReadAllTextAsync(manifestPath);
                var manifest = JsonSerializer.Deserialize<PluginManifest>(manifestJson);

                if (manifest == null)
                    return null;

                var entryPointPath = Path.Combine(pluginPath, manifest.EntryPoint);
                if (!File.Exists(entryPointPath))
                    return null;

                // 加载插件程序集
                var assembly = Assembly.LoadFrom(entryPointPath);
                var pluginType = assembly.GetTypes()
                    .FirstOrDefault(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsInterface);

                if (pluginType == null)
                    return null;

                var plugin = Activator.CreateInstance(pluginType) as IPlugin;
                return plugin;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"加载插件失败: {pluginPath}");
                return null;
            }
        }

        private async Task DownloadPluginAsync(string source, string targetPath)
        {
            // 简化实现：假设source是本地路径
            if (Directory.Exists(source))
            {
                CopyDirectory(source, targetPath);
            }
            else if (File.Exists(source))
            {
                // 假设是zip文件
                System.IO.Compression.ZipFile.ExtractToDirectory(source, targetPath);
            }
            else
            {
                throw new FileNotFoundException($"插件源不存在: {source}");
            }

            await Task.Delay(1); // 占位符
        }

        private void CopyDirectory(string sourceDir, string targetDir)
        {
            Directory.CreateDirectory(targetDir);

            foreach (var file in Directory.GetFiles(sourceDir))
            {
                var targetFile = Path.Combine(targetDir, Path.GetFileName(file));
                File.Copy(file, targetFile, true);
            }

            foreach (var subDir in Directory.GetDirectories(sourceDir))
            {
                var targetSubDir = Path.Combine(targetDir, Path.GetFileName(subDir));
                CopyDirectory(subDir, targetSubDir);
            }
        }

        private async Task UpdatePluginStatusAsync(string pluginId, PluginStatus status)
        {
            var installedPlugins = await GetInstalledPluginsAsync();
            var plugin = installedPlugins.FirstOrDefault(p => p.Id == pluginId);
            if (plugin != null)
            {
                plugin.Status = status;
                await _dataStorage.SaveAsync("installed_plugins", installedPlugins);
            }
        }

        private bool IsVersionCompatible(string installedVersion, string requiredVersion)
        {
            // 简化的版本兼容性检查
            try
            {
                var installed = new Version(installedVersion);
                var required = new Version(requiredVersion);
                return installed >= required;
            }
            catch
            {
                return false;
            }
        }

        private bool IsValidPermission(string permission)
        {
            var validPermissions = new[]
            {
                "file.read", "file.write", "network.access", "system.info",
                "ui.modify", "data.access", "ai.access", "project.modify"
            };

            return validPermissions.Contains(permission);
        }

        #endregion
    }
}
